import wx
import math

class Snake:
    def __init__ (self, step):
        self.step = step
        self.pts = list()
    
    def addpt (self, x, y):
        self.pts.append([float(x), float(y)])
        
    def transformCoords (self, fsize):
        disppts = list()
        for pt in self.pts:
            dpt = list()
            dpt.append(pt[0]/self.lastSize.width * fsize.width)
            dpt.append(pt[1]/self.lastSize.height * fsize.height)
            disppts.append(dpt)
        return disppts
    
    def getLines (self, disppts):
        lines = list()
        for pt in disppts:
            lines.append(wx.Point(pt[0], pt[1]))
        lines.append(wx.Point(pt[0],pt[1]))
        return lines
     
    def setLastSize (self, size):
        self.lastSize = size
class GVField:
    def __init__ (self, rows, cols, channels, u, v):
        self.rows = rows
        self.cols = cols
        self.channels = channels
        self.u = u
        self.v = v
    
    #NOTE there is a minimum resolution size we arent addressing here...
    #Also, integer rounding might be causing an issue
    #The mapping of the points onto the screen is off, see above?
    #Might be that the aspect ratio is weird....
    def genQuiver (self, size):
        veclen = 10.0   #in px
        #minimum resolution reached, changing veclen to compensate
        if (size.height / self.rows > veclen) or (size.width / self.cols > veclen):
            veclen = max(size.height / self.rows, size.width / self.cols) + 5
        arrowlen = max(veclen / 10.0,  4)
        #30px-wide blocks
        #ERROR 2 blocks can be added to both y and x...
        fxblocks = float(size.width) / veclen
        fyblocks = float(size.height) / veclen
        xblocks = int(fxblocks)
        yblocks = int(fyblocks)
        imghalfinc = veclen / 2.0
        #x=col,width y=row,height
        #NOTE index notation is list[y][x] -> ROW INDEXED!
        #Trying to keep list[0]->x list[1]->y for tuples, check this later...
        fieldhalfincx = veclen / 2.0 * float(self.cols) / float(size.width)
        fieldhalfincy = veclen / 2.0 * float(self.rows) / float(size.height)
        #fieldhalfincx = float(self.cols) / fxblocks / 2.0      #identical to above...
        #fieldhalfincy = float(self.rows) / fyblocks / 2.0
        fieldincx = veclen / float(size.width) * float(self.cols)
        fieldincy = veclen / float(size.height) * float(self.rows)
        vecs = list()
        arrows = list()
        thetas = list()
        maxdiff = 0
        mindiff = 1
        #print size, xblocks, yblocks
        #print fieldincx, self.cols / xblocks
        for i in range(0, xblocks):
            for j in range(0, yblocks):
                #could convert these to incremental vals outside of loop and just add them recursively later
                imgoffx = j * veclen
                imgoffy = i * veclen
                fieldoffx = j * fieldincx
                fieldoffy = i * fieldincy
                
                #get points at edge of box
                ixzero = min(int(fieldoffx),  self.cols-1)
                iyzero = min(int(fieldoffy), self.rows-1)
                ixhalf = min(int(fieldoffx + fieldhalfincx),  self.cols-1)
                iyhalf = min(int(fieldoffy + fieldhalfincy), self.rows-1)
                ixwhole = min(int(fieldoffx + fieldincx), self.cols-1)
                iywhole = min(int(fieldoffy + fieldincy),  self.rows-1)
                #get nearest neighbors
                #works, but doesnt get good differences
                """
                ixzero = ixhalf-1
                ixwhole = ixhalf+1
                iyzero = iyhalf-1
                iywhole = iyhalf+1
                """
                #print ixzero, iyzero, "h:", ixhalf, iyhalf, "w:", ixwhole, iywhole
                
                #dont need all of these values, just 4
                leftpt = [self.u[iyzero][ixhalf], self.v[iyzero][ixhalf]]
                toppt  = [self.u[iyhalf][ixzero], self.v[iyhalf][ixzero]]
                rightpt= [self.u[iywhole][ixhalf], self.v[iywhole][ixhalf]]
                botpt  = [self.u[iyhalf][ixwhole], self.v[iyhalf][ixwhole]]
                centerpt = [self.u[iyhalf][ixhalf], self.v[iyhalf][ixhalf]]
                
                diff = [leftpt[0] - rightpt[0], toppt[1] - botpt[1]]
                #Calculate scaling factors for vectors
                d = abs(diff[0] + diff[1])
                if d > maxdiff:
                    maxdiff = d
                if d < mindiff:
                    mindiff = d
                theta = math.pi/2.0
                if diff[0] != 0:
                    theta = math.atan(diff[1]/diff[0])
                thetas.append([theta, diff, imgoffy, imgoffx])
        #print mindiff, maxdiff
        for tuple in thetas:
            #scale it from 2->veclen
            theta = tuple[0]
            diff = tuple[1]
            imgoffy = tuple[2]
            imgoffx = tuple[3]
            #scale is from [0,1]
            scale = (diff[0] + diff[1] - mindiff)/maxdiff
            adjlen = (veclen - 5)*scale + 5
            #print adjlen, scale
            #print i, fieldincy, 30 / size.height * self.rows, fieldoffy, self.u[fieldoffy][fieldoffx + fieldhalfincx]
            #print rightpt[0], leftpt[0], toppt[1], botpt[1], theta
            imgvec = [ imgoffy + adjlen/2 * math.sin(theta), imgoffx + veclen/2 * math.cos(theta), imgoffy - adjlen/2 * math.sin(theta), imgoffx - adjlen/2 * math.cos(theta)]
            #if i == 5 and j == 5:
            #    print "5,5 img: ", imgvec[:]
            #    print "5,5 pts:", toppt, botpt, leftpt, rightpt
            
            arrowtheta1 = theta + math.pi/6.0 + math.pi
            arrowtheta2 = theta - math.pi/6.0 + math.pi
            arrowleft = [imgvec[0], imgvec[1], imgvec[0]+arrowlen*math.sin(arrowtheta1), imgvec[1]+arrowlen*math.cos(arrowtheta1)]
            arrowright = [imgvec[0], imgvec[1], imgvec[0]+arrowlen*math.sin(arrowtheta2), imgvec[1]+arrowlen*math.cos(arrowtheta2)]
            #print arrowleft
            vecs.append(imgvec)
            vecs.append(arrowleft)
            vecs.append(arrowright)
        #print "done", vecs[len(vecs)-3]
        return vecs
